// 使用ts需要把它转化成JS然后node执行，使用tsc或者tsc -w
const fs: any = require("fs");
const path: object = require("path");
const os: object = require("os");
const { addAbortSignal }: { addAbortSignal: object } = require("stream");
const { start }: { start: object } = require("repl");
// 写一个promise包裹后的重命名方法230909 核心奥义就是return一个promise对象，里面只有一个参数，就是回调方法
const findFile = (preName: string, newName: string): Promise<string> => {
    return new Promise((resolve, reject) => {
        fs.rename(preName, newName, (error: any, data: any) => {
            if (error) { reject(error) }
            resolve(data)
        });
    })
}
//修改前文件名，修改后的文件名。举例：myRename('test1.txt', 'test2.txt')
export const rename = (preName: string, newName: string) => {
    findFile(preName, newName).then(value => {
        // console.log('成功了', value);//value是undefined，所以这段没必要打印
    }, reason => {
        console.log('失败了', reason);
    })
}

// 判断是否文件夹，是文件夹true,不是返回false
export const isFold = (fileOrFoldName: any): boolean => fs.lstatSync(fileOrFoldName).isDirectory();


// 获取文件的大小
export const getFileSize = (file: string): { name: string, size: number } => {
    console.log(file, typeof (file));
    let msg = fs.statSync(file);
    // test.txt string 568kb的文件
    // { name: 'test.txt', size: 581360 }
    return {
        name: file,
        size: msg.size,
    };
}

// 该文件内的所有文件和文件夹数组
export const allFiles: string[] = fs.readdirSync(__dirname);

// 验证结尾后缀是否为真。str文件的名字。appoint文件后缀的名字
export const isValidationEnd = (str: string, appoint: string): boolean => {
    // 不区分大小写全部转换成小写。
    str = str.toLowerCase();
    let tempArr = str.split(".");
    let endStr = tempArr[tempArr.length - 1];
    if (appoint === endStr) {
        return true;
    }
    return false;
}
// 过滤数组的方法，返回我想要的文件类型的数组。第一个参数文件数组。第二个参数后缀名，字符串。
export const filterTypeArr = (arr = allFiles, typeStr: string): string[] => {
    let newArr = [];
    for (let i in arr) {
        if (isValidationEnd(arr[i], typeStr)) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}

// 过滤数组，只留下文件夹的数组 arr一般都是allFiles
export const onlyFoldArr = (arr = allFiles): string[] => {
    let newArr = [];
    for (let i in arr) {
        if (isFold(arr[i])) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}
// 验证是否是数字 只能判断一位数
function isNum(num: any): boolean {
    let pattern = /^[0-9]$/;
    /* let str='123'
      let str4='1'
      let str3='9'
      let str2='12a'
      console.log(pattern.test(str));
      console.log(pattern.test(str2));
      console.log(pattern.test(str3));
      console.log(pattern.test(str4)); */
    return pattern.test(num);
}
// 判断是否是小写 一位
function isLow(str: string): boolean {
    let pattern = /^[a-z]$/;
    return pattern.test(str);
}
interface FileMsgInterface {
    name: string;
    size: string;
    atime: any;
    ctime: any;
    mtime: any;
    birthtime: any;
    atimeString: string;
    ctimeString: string;
    mtimeString: string;
    birthtimeString: string;
    ctimeStringOnly10: string;
}
// 获取文件的所有信息
export const getFileMsg = (file: string): FileMsgInterface => {
    /* {
   dev: 1781885125,
   mode: 33206,
   nlink: 1,
   uid: 0,
   gid: 0,
   rdev: 0,
   blksize: 4096,
   ino: 281474976900432,
   size: 0,
   blocks: 0,
   atimeMs: 1689313507912.332,
   mtimeMs: 1689313507912.332,
   ctimeMs: 1689313514053.8118,
   birthtimeMs: 1689313507912.332,
   atime: 2023-07-14T05:45:07.912Z,
   mtime: 2023-07-14T05:45:07.912Z,
   ctime: 2023-07-14T05:45:14.054Z,
   birthtime: 2023-07-14T05:45:07.912Z
 } */
    const msg = fs.statSync(file);
    const { atime, mtime, ctime, birthtime } = msg
    let size: number | string = msg.size / 1024 / 1024;
    const re = /([0-9]+\.[0-9]{1})[0-9]*/;
    const jieQu = size.toString().replace(re, "$1");
    size = jieQu + "MB";
    /* {
        name: 'test.txt',
        size: '0.5MB',
        atime: 2023-09-09T10:59:13.337Z,
        mtime: 2023-09-09T10:59:03.823Z,
        ctime: 2023-09-09T10:59:13.291Z,
        birthtime: 2023-09-09T08:13:48.330Z
      } */
    // console.log(msg, typeof (msg.atime), typeof (msg.mtime));
    return {
        name: file,
        size,
        atime: atime,
        mtime: mtime,
        ctime: ctime,
        birthtime: birthtime,
        atimeString: timeStampToTime(msg.atime),
        mtimeString: timeStampToTime(msg.mtime),
        ctimeStringOnly10: timeStampToTime(msg.mtime).slice(0, 10),
        ctimeString: timeStampToTime(msg.ctime),
        birthtimeString: timeStampToTime(msg.birthtime),
    };
}
const { basename } = require('path')
const proPath = __dirname // 路径 "/Users/yangxin/code/lib"
export const thisFoldName = basename(proPath)//C:\Users\Carlos\Downloads\Compressed
// 过滤数组，只留下文件夹的数组 arr一般是allFiles
export const filterOnlyFoldArr = (arr: string[] = allFiles): string[] => {
    let newArr: string[] = []
    for (let i in arr) {
        if (isFold(arr[i])) {
            newArr.push(arr[i])
        }
    }
    return newArr
}
// 时间戳转化为时间
export const timeStampToTime = (timeStamp: any): string => {
    const date = new Date(timeStamp), // 参数需要毫秒数，所以这里将秒数乘于 1000
        Y = date.getFullYear() + "-",
        M = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-",
        h = date.getHours() + ":",
        m = date.getMinutes() + ":",
        s = date.getSeconds();
    let D = date.getDate() + " ";
    // if (((D as number)*1)< 10) {类型 "string" 到类型 "number" 的转换可能是错误的，因为两种类型不能充分重叠。如果这是有意的，请先将表达式转换为 "unknown"。所以必须要用parseint
    if (parseInt(D) < 10) {
        D = "0" + D
        // console.log('日期小于10', D);
    }
    const timeString = Y + M + D + h + m + s
    // console.log("timeString", timeString);
    return timeString;
}

// 不含尾缀的文件名比如test.txt=>test
export const fileNameWithoutSuffix = (file: string): string => {
    // 第一次是这样写，但是如果文件名带有.就不行了
    // return file.split('.')[0]
    const lastPointIndex = file.lastIndexOf(".");
    const noSuffixName = file.slice(0, lastPointIndex)
    // console.log('111',file.split('.'));//[ '23', '09', '10test2023-09-09王乘乘92023+09-99', 'txt' ]
    // console.log('newww', noSuffixName);
    return noSuffixName;
};


/**
 * 判断这个文件的名字结尾是否已经有了时间后缀，有返回真，没有返回假
 * @param {string} file 包含后缀名的文件名
 * @param {string} timeType timeType时间的格式 一般都是'0000-00-00'
 * @param {string} inclueTimeType 额外时间的格式 一般都是'00.00.00'以及'230910这种' 这个格式可以暂时不要
 * @return {boolean} 是否符合时间格式要求规范
 */
interface DashObjInterface {
    item: string;
    index: number;
}
export const isFileNameIncludeDate = (file: string, timeType = '0000-00-00',): boolean => {
    //test2023-09-09.txt
    const conciseFile = fileNameWithoutSuffix(file);
    if (conciseFile.length < 7) return false;
    // const dateReg = /^\d{2,4}(\.)\d{1,2}\1\d{1,2}$/;
    const dateReg = /\d{2,4}(\.)\d{1,2}\1\d{1,2}/;
    // 时间以1-2开头的 2023 23这种都可 20230910 6位数或者8位数
    const dateRegNoPoint = /[1,2]\d{5,7}/;
    // console.log(dateReg.test(conciseFile), dateRegNoPoint.test(conciseFile));
    // false,false
    if (dateReg.test(conciseFile) || dateRegNoPoint.test(conciseFile)) {
        return true;
    }

    // 这俩都是index【】
    const numberArr: number[] = []
    const dashArr: DashObjInterface[] = []
    const { length } = timeType;
    for (let index = 0; index < length; index++) {
        let item = timeType[index];
        if (isNum(item)) {
            numberArr.push(index);
        } else {
            dashArr.push({ item, index })
        }
    }
    // 将file和timeType对比
    // push,unshift不改变原数组地址，所以即使是const数组也不影响
    // 只要有一个不是数字则通过some，也就是不符合规范，所以返回假
    const _conciseFile = conciseFile.slice(-length)
    if (numberArr.some(item => {
        /* { item: '2', index: 0 },*/
        return !isNum(_conciseFile[item])
    })) return false;
    if (dashArr.some(dashObj => {
        const { item, index } = dashObj
        return !(_conciseFile[index] === item)
    })) return false;

    return true;
}



// 重命名文件，增加日期信息，第一个是文件的类型，我一般是mp4，第二个是额外名字信息比如 李永乐老师
export const handleRenamaAddDateAndMsg = (filetype: string, moreInformation?: string) => {
    const typeArray = filterTypeArr(allFiles, filetype);
    typeArray.forEach(item => {
        const suffixArr = item.split("." + filetype);
        const noSuffixItem = suffixArr[0];
        // console.log(item,'item');
        let newName = moreInformation && item.indexOf(moreInformation) === -1 ? noSuffixItem + moreInformation + getFileMsg(item).ctimeStringOnly10 + "." + filetype : noSuffixItem + getFileMsg(item).ctimeStringOnly10 + "." + filetype;
        // 没有时间后缀才重命名，有就不重新命名
        if (!isFileNameIncludeDate(item)) {
            rename(item, newName)
            console.log('后缀和日期添加成功！');
        } else {
            console.log('该文件已经有了该时间后缀名！无法重新命名！');
        };
    })

}



// 测试代码
// console.log('a',allFiles);
// console.log(getSize('test.txt'));
// rename('test1.txt', 'test2.txt')
// console.log(getFileMsg('test.txt'));
// console.log(isFileNameIncludeDate('23.09.10test2023-09-09王乘乘92023+09-99.txt'));//这样的时期格式才会返回真
